package main.java.chessfootball.model.regulation;

import main.java.chessfootball.model.game.Side;
import main.java.chessfootball.model.game.Uniform;
import main.java.chessfootball.model.rule.MatchRule;
import main.java.chessfootball.model.rule.TimeRule;

/**
 * User: Igor
 * Date: 11.06.2011
 * Time: 8:42:36
 */
public class Match
{
	private Mode mode;
	private Time time;
	private Score score;

	public Match(Mode mode, Time time, Score score)
	{
		this.mode = mode;
		this.time = time;
		this.score = score;
	}

	public void move()
	{
		time.move();
	}

	public void turnInGame()
	{
		time.turn();
		time.changeSide();
	}

	public void goal(Side side)
	{
		score.goal(side);
		time.turn();
		time.changeSide();
		mode = mode.getInvert();
	}

	public void nextPeriod(MatchRule rule)
	{
		mode = Mode.OUT_GAME;
		TimeRule timeRule = rule.getTimeRule(time.getPeriod());
		int nextTimeRuleIdx = rule.getTimes().indexOf(timeRule) + 1;
		TimeRule nextTimeRule = null;
		if (nextTimeRuleIdx < rule.getTimes().size())
		{
			nextTimeRule = rule.getTimes().get(nextTimeRuleIdx);
			time = new Time(rule.getStartTurns(nextTimeRule.getPeriod()), 0
					, nextTimeRule.getPeriod()
					, rule.getStartSide(nextTimeRule.getPeriod())
					, rule.getStartSide(nextTimeRule.getPeriod())
					, rule.getEndTurns(nextTimeRule.getPeriod())
					);
		}
	}

	public void goInGame()
	{
		mode = Mode.IN_GAME;
		time.changeSide();
	}

	public void turnOutGame()
	{
		time.changeSide();
	}

	public boolean isEndOfTime(MatchRule rule, Side sideOfGoal)
	{
		TimeRule timeRule = rule.getTimeRule(time.getPeriod());
		if (time.getEndOfTime() <= time.getTurns() + 1)
		{
			return true;//todo timeRule.completionAttack
		}
		if (rule.getScoreLimit() != null)
		{
			for (Side side: Side.values())
			{
				if (score.getScore(side) >= rule.getScoreLimit())
				{
					return true;
				}
			}
		}
		return (sideOfGoal != null) && (timeRule.isGoldenGoal());
	}

	public Mode getMode()
	{
		return mode;
	}

	public Time getTime()
	{
		return time;
	}

	public Score getScore()
	{
		return score;
	}

	@Override
	public String toString()
	{
		StringBuilder sb = new StringBuilder();
		sb.append(Uniform.BLUE);
		sb.append(" ");
		sb.append(score);
		sb.append(" ");
		sb.append(Uniform.RED);
		sb.append("   ");
		sb.append(time.getTurns());
		sb.append(":");
		sb.append(60 * time.getMoves() / 3);
		sb.append("   ");
		sb.append(time.getPeriod());
		sb.append("   ");
		sb.append(mode);
		sb.append("   ");
		sb.append("Turn : ").append(time.getTurnSide());
		return sb.toString();
	}
}
